﻿/*
 * 表达式树是定义代码的数据结构
 * 
 */

//using System.Linq.Expressions;

//Expression<Func<int, int>> addFive = (num) => num + 5;

//if (addFive.NodeType == ExpressionType.Lambda)
//{

//    var lambdaExp = (LambdaExpression)addFive;

//    var parameter = lambdaExp.Parameters.First();

//    Console.WriteLine(parameter.Name);
//    Console.WriteLine(parameter.Type);
//}

//var one = Expression.Constant(1, typeof(int));
//var two = Expression.Constant(2, typeof(int));
//var addition = Expression.Add(one, two);
//Console.WriteLine(addition);

//Expression<Func<int>> add = () => 1 + 2;
//var func = add.Compile(); // Create Delegate
//var answer = func(); // Invoke Delegate
//Console.WriteLine(answer);

////2,-3,-5
//Expression<Func<double, double, double, double>> aa = (a, b, c) => (-b + Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
//Expression<Func<double, double, double, double>> bb = (a, b, c) => (-b - Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
//var funcs = aa.Compile();
//var funcss = bb.Compile();
//var tt = funcs(2, -3, -5);
//var ttt = funcss(2, -3, -5);
//Console.WriteLine(tt);
//Console.WriteLine(ttt);


using System.Linq.Expressions;

//Expression<Func<int, int, int>> addition = (a, b) => a + b;
Expression<Func<double, double, double, double>> addition = (a, b, c) => (-b + Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
Console.WriteLine($"This expression is a {addition.NodeType} expression type");
Console.WriteLine($"The name of the lambda is {((addition.Name == null) ? "<null>" : addition.Name)}");
Console.WriteLine($"The return type is {addition.ReturnType.ToString()}");
Console.WriteLine($"The expression has {addition.Parameters.Count} arguments. They are:");
foreach (var argumentExpression in addition.Parameters)
{
    Console.WriteLine($"\tParameter Type: {argumentExpression.Type.ToString()}, Name: {argumentExpression.Name}");
}

var additionBody = (BinaryExpression)addition.Body;
Console.WriteLine($"The body is a {additionBody.NodeType} expression");
Console.WriteLine($"The left side is a {additionBody.Left.NodeType} expression");
var left = (ParameterExpression)additionBody.Left;
Console.WriteLine($"\tParameter Type: {left.Type.ToString()}, Name: {left.Name}");
Console.WriteLine($"The right side is a {additionBody.Right.NodeType} expression");
var right = (ParameterExpression)additionBody.Right;
Console.WriteLine($"\tParameter Type: {right.Type.ToString()}, Name: {right.Name}");

